package com.biz.primus.ms.oms.service.core;

import com.biz.primus.base.vo.PageResult;
import com.biz.primus.common.utils.Copier;
import com.biz.primus.common.utils.CopyUtils;
import com.biz.primus.common.utils.StringUtil;
import com.biz.primus.model.oms.enums.OrderInterceptType;
import com.biz.primus.model.oms.enums.TimeoutHandleState;
import com.biz.primus.model.oms.vo.OrderInterceptQueryVo;
import com.biz.primus.model.oms.vo.OrderInterceptVo;
import com.biz.primus.ms.base.service.AbstractBaseService;
import com.biz.primus.ms.oms.dao.po.OrderIntercept;
import com.biz.primus.ms.oms.dao.po.OrderTimeoutRecord;
import com.biz.primus.ms.oms.dao.repository.OrderInterceptRepository;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.persistence.criteria.Predicate;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class OrderInterceptServiceImpl extends AbstractBaseService implements OrderInterceptService {


    @Autowired
    private OrderInterceptRepository orderInterceptRepository;


    @Override
    public void saveOrderIntercept(List<OrderInterceptVo> orderInterceptVos) {
        List<OrderIntercept> orderIntercepts = orderInterceptVos.stream().map(req ->vo2Po(req)).collect(Collectors.toList());
        orderInterceptRepository.save(orderIntercepts);
    }

    @Override
    public void delOrderIntercept(String id) {
        if(!StringUtil.isNullOrEmpty(id)){
            orderInterceptRepository.delete(Long.valueOf(id));
        }
    }

    @Override
    public void setState(String id,boolean state) {
        if(!StringUtil.isNullOrEmpty(id)){
            OrderIntercept orderIntercept = orderInterceptRepository.findOne(Long.valueOf(id));
            orderIntercept.setState(state);
            orderInterceptRepository.save(orderIntercept);
        }
    }

    @Override
    public PageResult<OrderInterceptVo> findAllOrderIntercept(OrderInterceptQueryVo orderInterceptQueryVo) {
        Page<OrderIntercept> orderIntercepts = orderInterceptRepository.findAll(orderInterceptQueryVo.toPageRequest());
        List<OrderInterceptVo> orderInterceptVos = orderIntercepts.getContent().stream().map(po -> po2Vo(po)).collect(Collectors.toList());
        return PageResult.of(orderIntercepts.getNumber(),orderIntercepts.getTotalPages(),orderInterceptVos);
     }

    @Override
    public List<OrderInterceptVo> findByStateAndType(List<OrderInterceptType> orderInterceptTypes) {

        List<OrderIntercept> orderIntercepts = orderInterceptRepository.findAll((root, cq, cb) -> {
            List<Predicate> predicates = Lists.newArrayList();
            predicates.add(cb.equal(root.get("state").as(Boolean.class), true));
            predicates.add(root.get("orderInterceptType").in(orderInterceptTypes));
            return cb.and(predicates.stream().toArray(Predicate[]::new));
        });
        return orderIntercepts.stream().map(po -> Copier.from(po).to(new OrderInterceptVo())).collect(Collectors.toList());
    }

    public OrderInterceptVo po2Vo(OrderIntercept orderIntercept){
        OrderInterceptVo orderInterceptVo =new OrderInterceptVo();
        orderInterceptVo.setCreateTimestamp(orderIntercept.getCreateTimestamp());
        orderInterceptVo.setIdStr(String.valueOf(orderIntercept));
        orderInterceptVo.setOrderInterceptType(orderIntercept.getOrderInterceptType());
        orderInterceptVo.setPropertyName(orderIntercept.getPropertyName());
        orderInterceptVo.setPropertyValue(orderIntercept.getPropertyValue());
        orderInterceptVo.setState(orderIntercept.isState());
        return orderInterceptVo;
    }

    public OrderIntercept vo2Po(OrderInterceptVo orderInterceptVo){
        OrderIntercept orderIntercept =new OrderIntercept();
        orderIntercept.setCreateTimestamp(orderInterceptVo.getCreateTimestamp());
        orderIntercept.setId(idService.getNextId());
        orderIntercept.setOrderInterceptType(orderInterceptVo.getOrderInterceptType());
        orderIntercept.setPropertyName(orderInterceptVo.getPropertyName());
        orderIntercept.setPropertyValue(orderInterceptVo.getPropertyValue());
        orderIntercept.setState(orderInterceptVo.isState());
        return orderIntercept;
    }

}
